package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tanhua.domain.Scores;
import com.tanhua.domain.db.Questionnaire;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Report;
import com.tanhua.domain.mongo.ReportUser;
import com.tanhua.domain.vo.AnswersVo;
import com.tanhua.domain.vo.QuestionnaireVo;
import com.tanhua.domain.vo.ReportVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.SoulTestApi;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author HoshizoraL
 * @Date 2021/4/20 10:43
 */
@Service
public class SoulTestService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private SoulTestApi soulTestApi;

    private final static String REDISKEY = "REPORT_";

    /**
     * 根据Id从redis获取报告
     * @param id
     * @return
     */
    public ReportVo getReport(String id) {
        ReportVo vo = new ReportVo();
        Long userId = UserHolder.getUserId();
        String key = REDISKEY + id;
        //根据id从redis中获取，如果没有则查询数据库，获取后存入redis
        String reportStr = (String) redisTemplate.opsForValue().get(key);
        Report report = null;
        if (StringUtils.isEmpty(reportStr)) {
            report = soulTestApi.getReportById(id);
            reportStr = JSON.toJSONString(report);
            redisTemplate.opsForValue().set(key,reportStr);
        } else {
            JSONObject jsonObject = JSONObject.parseObject(reportStr);
            report = JSONObject.toJavaObject(jsonObject,Report.class);
        }
        BeanUtils.copyProperties(report,vo);
        //将userId reportId 和CreatedTime存入一个新数据库
        ReportUser ru = new ReportUser();
        ru.setId(ObjectId.get());
        ru.setCreatedTime(System.currentTimeMillis());
        ru.setUserId(userId);
        ru.setReportId(new ObjectId(id));
        soulTestApi.saveReportUser(ru);
        //查询数据库，获取报告id相同的userId集合，根据创建时间排序获取11个用户(排除本人)
        List<ReportUser> userIds = soulTestApi.findUsers(id,11);
        //如果存在就会被移除
        List<UserInfo> list = new ArrayList<>();
        for (ReportUser reportUser : userIds) {
            UserInfo info = userInfoApi.findByUserId(reportUser.getUserId());
            if (info == null || info.getId().equals(userId)) {
                continue;
            }
            list.add(info);
        }
        vo.setSimilarYou(list);
        return vo;
    }

    /**
     * 获取报告Id
     * @param answers
     * @return
     */
    public String getReportId(List<AnswersVo> answers) {
        Long userId = UserHolder.getUserId();
        //获取选项及题目难度
        String questionId = answers.get(0).getQuestionId();
        Long testId = soulTestApi.getTest(questionId);
        //计算分数
        int score = 0;
        for (AnswersVo answer : answers) {
            String optionId = answer.getOptionId();
            switch (optionId) {
                case "1":
                    score += Scores.SCORE_A;
                    break;
                case "2":
                    score += Scores.SCORE_B;
                    break;
                case "3":
                    score += Scores.SCORE_C;
                    break;
                case "4":
                    score += Scores.SCORE_D;
                    break;
                default:break;
            }
        }
        //更新题库等级
        soulTestApi.updateLock(userId,testId);
        //根据分数及问卷Id获取reportId返回
        Report report = soulTestApi.getReportId(score,testId);
        return report.getId().toHexString();
    }

    public List<QuestionnaireVo> questionnaireList() {
        Long userId = UserHolder.getUserId();
        //获取用户题库等级
        int lock = soulTestApi.getLock(userId);
        //构建一个Volist,用来封装数据
        List<QuestionnaireVo> voList = soulTestApi.findTests();
        for (QuestionnaireVo vo : voList) {
            if (vo.getStar() <= lock) {
                vo.setIsLock(0);
            }
        }
        return voList;
    }
}
